﻿using System;
using System.Linq;
using System.Linq.Expressions;
//using System.Windows;
using Microsoft.VisualStudio.TestTools.UnitTesting;


namespace ExpressionSerialization
{
  [TestClass]
  public class Tests
  {

    [TestMethod()]
    public void PartConstant()
    {
      Object[] values = new object[] { "bike", Guid.NewGuid(), DateTime.Now, 123, -123, long.MaxValue, long.MinValue, 3.14D, -3.14D, 12.99M, -12.99M };

      foreach(var item in values) {
        ConstantExpression exp = Expression.Constant(item);

        string ss = exp.SerializeToString();
        ConstantExpression exp2 = ExpressionExtension.DeserializeFromString(ss) as ConstantExpression;
        //var xx = XExpression.CreateFromExpression(exp);
        //ConstantExpression exp2 = xx.ToExpression() as ConstantExpression;

        Assert.AreEqual(exp.Type, exp2.Type, "Constant - Type");
        Assert.AreEqual(exp.NodeType, exp2.NodeType, "Constant - NodeType");
        Assert.AreEqual(exp.Value, exp2.Value, "Constant - Name");
      }
    }

    [TestMethod()]
    public void PartParameter()
    {
      ParameterExpression exp = Expression.Parameter(typeof(ProductLocal), "e");

      string ss = exp.SerializeToString();
      ParameterExpression exp2 = ExpressionExtension.DeserializeFromString(ss) as ParameterExpression;
      //var xx = XExpression.CreateFromExpression(exp);
      //ParameterExpression exp2 = xx.ToExpression() as ParameterExpression;

      Assert.AreEqual(exp.Type, exp2.Type, "Parameter - Type");
      Assert.AreEqual(exp.NodeType, exp2.NodeType, "Parameter - NodeType");
      Assert.AreEqual(exp.Name, exp2.Name, "Parameter - Name");
      Assert.AreEqual(exp.IsByRef, exp2.IsByRef, "Parameter - IsByRef");
    }

    [TestMethod()]
    public void PartMember()
    {
      ParameterExpression p = Expression.Parameter(typeof(ProductLocal), "e");
      MemberExpression exp = Expression.Property(p, "Name");

      string ss = exp.SerializeToString();
      MemberExpression exp2 = ExpressionExtension.DeserializeFromString(ss) as MemberExpression;
      //var xx = XExpression.CreateFromExpression(exp);
      //MemberExpression exp2 = xx.ToExpression() as MemberExpression;

      Assert.AreEqual(exp.Type, exp2.Type, "Member - Type");
      Assert.AreEqual(exp.NodeType, exp2.NodeType, "Member - NodeType");
      Assert.AreEqual(exp.Member.ToString(), exp2.Member.ToString(), "Member - Member");
    }

    [TestMethod()]
    public void PartMethodCalll()
    {
      ParameterExpression p = Expression.Parameter(typeof(ProductLocal), "e");
      MemberExpression fieldName = Expression.Property(p, "Name");

      ConstantExpression ecBike = Expression.Constant("bike");
      MethodCallExpression exp = Expression.Call(fieldName, typeof(String).GetMethod("Contains", new[] { typeof(string) }), ecBike);

      string ss = exp.SerializeToString();
      MethodCallExpression exp2 = ExpressionExtension.DeserializeFromString(ss) as MethodCallExpression;
      //var xx = XExpression.CreateFromExpression(exp);
      //MethodCallExpression exp2 = xx.ToExpression() as MethodCallExpression;

      Assert.AreEqual(exp.Type, exp2.Type, "MethodCall - Type");
      Assert.AreEqual(exp.NodeType, exp2.NodeType, "MethodCall - NodeType");
      Assert.AreEqual(exp.Method.ToString(), exp2.Method.ToString(), "MethodCall - Method");
      Assert.AreEqual(exp.Arguments.Count, exp2.Arguments.Count, "MethodCall - Arguments");
    }

    [TestMethod()]
    public void PartBinary()
    {
      ParameterExpression p = Expression.Parameter(typeof(ProductLocal), "e");
      MemberExpression fieldName = Expression.Property(p, "Name");

      ConstantExpression ecBike = Expression.Constant("bike");
      MethodCallExpression ex1 = Expression.Call(fieldName, typeof(String).GetMethod("Contains", new[] { typeof(string) }), ecBike);

      ConstantExpression ecMountain = Expression.Constant("Mount");
      MethodCallExpression ex2 = Expression.Call(fieldName, typeof(String).GetMethod("Contains", new[] { typeof(string) }), ecMountain);

      BinaryExpression exp = BinaryExpression.And(ex1, ex2);


      string ss = exp.SerializeToString();
      BinaryExpression exp2 = ExpressionExtension.DeserializeFromString(ss) as BinaryExpression;
      //var xx = XExpression.CreateFromExpression(exp);
      //BinaryExpression exp2 = xx.ToExpression() as BinaryExpression;

      Assert.AreEqual(exp.Type, exp2.Type, "Binary - Type");
      Assert.AreEqual(exp.NodeType, exp2.NodeType, "Binary - NodeType");
      //Assert.AreEqual(exp.Method.ToString(), exp2.Method.ToString(), "Binary - Method");
      Assert.AreEqual(exp.Right.NodeType, exp2.Right.NodeType, "Binary - Right");
      Assert.AreEqual(exp.Left.NodeType, exp2.Left.NodeType, "Binary - Left");
    }
  }
}